/*----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the 
License at http://www.mozilla.org/MPL/
	
Software distributed under the License is distributed on 
an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, 
either express or implied. 
See the License for the specific language governing rights and 
limitations under the License.
	
The Original Code is Fever RS ( ActionScript 3 ) Framework code.
	
The Initial Developer of the Original Code is Romain Ecarnot.
Portions created by Initial Developer are Copyright (C) 2006
the Initial Developer. All Rights Reserved.
	
Contributor(s):
	
Unless required by applicable law or agreed to in writing, 
software distributed under the License is distributed on 
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
OF ANY KIND, either express or implied.
See the License for the specific language governing permissions 
and limitations under the License.
----------------------------------------------------------------------------*/

package fever.plugin.analytic 
{
	import com.bourre.commands.ASyncCommandEvent;
	import com.bourre.commands.ASyncCommandListener;
	import com.bourre.plugin.AbstractPlugin;
	import com.bourre.plugin.ChannelExpert;
	
	import fever.commands.DelayedBatch;
	import fever.core.RSCore;
	import fever.events.AnalyticEvent;
	import fever.plugin.analytic.AnalyticTracker;
	import fever.utils.Stringifier;	

	/**
	 * <strong>Analytic</strong> plugin.
	 * 
	 * @example
	 * <listing version="3.0">
	 * 
	 *   RSCore.trackLink( "doc/myPDF.pdf", AnalyticLinkType.DOWNLOAD_LINK );
	 * </listing>
	 * 
	 * <p><strong>AnalyticPlugin</strong> can be loaded by <strong>I.O.C.</strong> 
	 * application context xml file, or automatically by the 
	 * <strong>Fever RS</strong> core if <strong>Analytic</strong> plugin is 
	 * not already loaded.</p>
	 * 
	 * @example <strong>I.O.C.</strong> application context
	 * <listing version="3.0">
	 * 
	 * &lt;beans&gt;
	 * 	
	 * 	&lt;dll id="ap" url="resources/dll/AnalyticPlugin.swf" /&gt;
	 * 	&lt;dll id="apg" url="resources/dll/GoogleAnalyticStrategy.swf" /&gt;
	 * 	
	 * 	&lt;object id="GoogleAnalytic" type="fever.plugin.analytic.strategy.GoogleAnalytic" /&gt;
	 * 	
	 * 	&lt;plugin id="analytic" channel="MyAnalyticChannel" type="fever.plugin.analytic.AnalyticPlugin"&gt;
	 * 		&lt;method-call name="register"&gt;
	 * 			&lt;argument ref="GoogleAnalytic" /&gt;
	 * 		&lt;/method-call&gt;
	 * 	&lt;/plugin&gt;
	 * 	
	 * &lt;/beans&gt;
	 * </listing>
	 * 
	 * <p>If no <strong>I.O.C.</strong> is used, <strong>Fever RS</strong> automatically 
	 * call <strong>PluginRuntimeLoader.loadClass(...)</strong> to load the plugin.<br />
	 * Thus, plugin channel is available and tracking works properly as plugin was loaded.</p>
	 */
	public class AnalyticPlugin extends AbstractPlugin implements ASyncCommandListener
	{
		//--------------------------------------------------------------------
		// Private properties
		//--------------------------------------------------------------------
		
		private var _dTrackers : DelayedBatch;
		private var _eStored : AnalyticEvent;
		

		//--------------------------------------------------------------------
		// Public API
		//--------------------------------------------------------------------
		
		/**
		 * Registers passed-in <code>tracker</code> to manager.
		 * 
		 * @param tracker New tracker type.
		 * 
		 * @return <code>true</code> if tracker is corretly removed.
		 */
		public function register( tracker : AnalyticTracker ) : Boolean
		{
			RSCore.getLogger().info( "Register new Analytic Strategy " + tracker );
			
			return _dTrackers.addCommand( tracker );
		}
		
		/**
		 * Unregisters passed-in <code>tracker</code> to manager.
		 * 
		 * @param tracker New tracker type.
		 * 
		 * @return <code>true</code> if tracker is corretly removed.
		 */
		public function unregister( tracker : AnalyticTracker ) : Boolean
		{
			return _dTrackers.removeCommand( tracker );
		}
		
		/**
		 * Removes all trackers from manager.
		 */
		public function clear( ) : void
		{
			_dTrackers.removeAll();	
		}
			
		/**
		 * Tracks passed-in <code>event</code> tracking datas.
		 * 
		 * @param event <strong>AnalyticEvent</strong> containing tracking datas.
		 * 
		 * @see #track
		 * @see fever.events.AnalyticEvent
		 */
		public function onTrackLink( event : AnalyticEvent ) : void
		{
			getLogger().info( "Analytic tracking on " + getChannel() + " -> " + event.type + " | " + event.linkURL + " | " + event.linkType );
			
			_eStored = event;
			_dTrackers.execute( _eStored );
		}
		
		/**
		 * @private
		 * Triggered when all trackers do their jobs.
		 */
		public function onCommandEnd( e : ASyncCommandEvent ) : void
		{
			_eStored.type = AnalyticEvent.onTrackLinkDoneEVENT;
			
			firePublicEvent( _eStored );
		}
		
		/**
		 * Returns string representation.
		 */
		override public function toString() : String
		{
			return Stringifier.parse( this );
		}
		
		
		//--------------------------------------------------------------------
		// Private implementations
		//--------------------------------------------------------------------
		
		/**
		 * @private
		 * Private constructor
		 */
		public function AnalyticPlugin( )
		{
			super();
			
			AnalyticChannel = ChannelExpert.getInstance().getChannel( this );
			
			_dTrackers = new DelayedBatch( 200 );
			_dTrackers.addASyncCommandListener( this );
		}
	}
}